home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / mktil16a.zip / HEADERS.ZIP / FONT.H next >
C/C++ Source or Header  |  1994-09-15  |  9KB  |  416 lines

  1. /* make sure stdlib.h is in */
  2.  
  3. #ifndef _FAR_
  4.  #include <stdlib.h>
  5. #endif
  6.  
  7. #ifndef NORMAL
  8.  #define INVERSE 0
  9.  #define NORMAL 1
  10.  #define MASK 2
  11.  #define ERASE 3
  12.  #define ERASE_INVERSE 4
  13. #endif
  14.  
  15. #ifndef byte
  16.  #define byte unsigned char
  17.  #define word unsigned int
  18.  #define d_word unsigned long
  19. #endif
  20.  
  21. /* in case graphics.h is not going... */
  22.  
  23. #ifndef SCREEN
  24.  #define SCREEN (byte huge *)0xA0000000
  25.  byte huge *screen;
  26. #endif
  27.  
  28. #define FONT_CHARACTERS 256
  29. #define FONT_CHARACTER_SIZE 8
  30. #define FONT_X 8
  31. #define FONT_Y 8
  32.  
  33. byte huge **font;
  34.  
  35. /****************************************************************************/
  36. /****************************************************************************/
  37. /****************************************************************************/
  38.  
  39. void put_font(int x, int y, byte ascii, byte color, byte option)
  40. {
  41.  
  42. /* set up tileseg and tileoff with the segment and offset of the font */
  43. /* scrnseg and scrnoff contain the segment and offset of the screen buffer
  44.    which, if I assigned it to Video Mem, would be 0xA000 and 0x0000 
  45.    respectively */
  46.  
  47.  word tileseg=FP_SEG(font[ascii]),
  48.      tileoff=FP_OFF(font[ascii]),
  49.      scrnseg=FP_SEG(screen),
  50.      scrnoff=FP_OFF(screen)+(y<<8)+(y<<6)+x;
  51.  
  52. /* normal just draws the character's on pixesl.  black is transparent. */
  53.  
  54.  if (option==NORMAL)
  55.  {
  56.   _asm
  57.   {
  58. /* save the data segment */
  59.  
  60.    push    ds
  61.  
  62. /* load ds:si register pair with segment and offset of font */
  63.  
  64.    mov     ax,[tileseg]
  65.    mov     ds,ax
  66.    mov     si,[tileoff]
  67.  
  68. /* likewise, load es:di register pair with segment:offset of where to
  69.    put it */
  70.  
  71.    mov     ax,[scrnseg]
  72.    mov     es,ax
  73.    mov     di,[scrnoff]
  74.  
  75. /* Alow contains the color to draw the font with, and cx is our loop var. */
  76.  
  77.    mov     al,[color]
  78.    mov     cx,FONT_Y
  79.  
  80.    start:
  81.    push    cx
  82.  
  83. /* get a byte of the font.  this is 8 pixels.  */
  84.  
  85.    mov     bl,[si]
  86.    mov     cx,FONT_X
  87.  
  88. /* now we loop through the byte using a shift and draw each pixel. */
  89.  
  90.    mid:
  91.  
  92. /* copy the byte so we can keep the original. */
  93.  
  94.    mov     bh,bl
  95.  
  96. /* keep the 1st bit which is the pixel we wish to draw */
  97.  
  98.    and     bh,0x01
  99.  
  100. /* if the bit is 1, it is on, and so we draw it.  */
  101.  
  102.    dec     bh
  103.    jz      draw
  104.  
  105. /* otherwise, skip and continue... */
  106.  
  107.    jmp     mid_end
  108.  
  109.    draw:
  110.  
  111. /* move the 'color' (which was in Alow) to the screen (buffer or wherever) */
  112.  
  113.    mov     es:[di],al
  114.  
  115.    mid_end:
  116.  
  117. /* shift the byte to the right.  it's like a conveyor belt...after we process
  118.    each bit, we throw off the right-most one (or left-most; it depends how you
  119.    look at it: I see it from right to left here...00000001 is 1, 00000010
  120.    is 2, etc.) and take the next-leftmost bit. 10101010 would become 01010101
  121. */
  122.  
  123.    shr     bl,1
  124.  
  125. /* move over one pixel on the screen (where we're drawing) */
  126.  
  127.    inc     di
  128.  
  129. /* finish processing the remaining bits in the byte we fetched */
  130.  
  131.    loop    mid
  132.  
  133. /* ok, now we get the next byte */
  134.  
  135.    inc     si
  136.  
  137. /* and, to draw the next 8 pixels 'under' the 1st 8, we go DOWN 1 vertical
  138.    screen row (+320 bytes) and subtract 8 horizontal pixels (-8 bytes). */
  139.  
  140.    add     di,320-FONT_X
  141.  
  142.    pop     cx
  143.  
  144. /* finished */
  145.  
  146.    loop start
  147.  
  148.    end:
  149.  
  150. /* restore data segment */
  151.  
  152.    pop     ds
  153.   }
  154.  }
  155.  else if (option==INVERSE)
  156.  {
  157.  
  158. /* this is basically the same as above... */
  159.  
  160.   _asm
  161.   {
  162.    push    ds
  163.  
  164.    mov     ax,[tileseg]
  165.    mov     ds,ax
  166.    mov     si,[tileoff]
  167.  
  168.    mov     ax,[scrnseg]
  169.    mov     es,ax
  170.    mov     di,[scrnoff]
  171.  
  172.    mov     al,[color]
  173.    mov     cx,FONT_Y
  174.  
  175.    start2:
  176.    push    cx
  177.  
  178.    mov     bl,[si]
  179.    mov     cx,FONT_X
  180.  
  181.    mid2:
  182.    mov     bh,bl
  183.    and     bh,0x01
  184.  
  185. /* but instead of drawing on 1, we draw on 0. 1's are transparent.  */
  186.  
  187.    dec     bh
  188.    jnz     draw2
  189.    jmp     mid_end2
  190.  
  191.    draw2:
  192.    mov     es:[di],al
  193.  
  194.    mid_end2:
  195.    shr     bl,1
  196.    inc     di
  197.    loop    mid2
  198.  
  199.    inc     si
  200.    add     di,320-FONT_X
  201.  
  202.    pop     cx
  203.    loop start2
  204.  
  205.    end2:
  206.    pop     ds
  207.   }
  208.  }
  209.  else if (option==ERASE)
  210.  {
  211.  
  212. /* this is slightly different. we draw 1's, but ERASE 0's. */
  213.  
  214.   _asm
  215.   {
  216.    push    ds
  217.  
  218.    mov     ax,[tileseg]
  219.    mov     ds,ax
  220.    mov     si,[tileoff]
  221.  
  222.    mov     ax,[scrnseg]
  223.    mov     es,ax
  224.    mov     di,[scrnoff]
  225.  
  226.    mov     al,[color]
  227.    mov     cx,FONT_Y
  228.  
  229.    start3:
  230.    push    cx
  231.  
  232.    mov     bl,[si]
  233.    mov     cx,FONT_X
  234.  
  235.    mid3:
  236.    mov     bh,bl
  237.    and     bh,0x01
  238.    dec     bh
  239.    jz      draw3
  240.  
  241. /* go ahead and draw 1's, but... */
  242.  
  243. /* erase any 'off' pixels by a 0 to screen memory. */
  244.  
  245.    mov     es:[di],0
  246.    jmp     mid_end3
  247.  
  248.    draw3:
  249.    mov     es:[di],al
  250.  
  251.    mid_end3:
  252.    shr     bl,1
  253.    inc     di
  254.    loop    mid3
  255.  
  256.    inc     si
  257.    add     di,320-FONT_X
  258.  
  259.    pop     cx
  260.    loop start3
  261.  
  262.    end3:
  263.    pop     ds
  264.   }
  265.  }
  266. }
  267.  
  268. /****************************************************************************/
  269. /****************************************************************************/
  270. /****************************************************************************/
  271.  
  272. /* this just uses put_font() to display a string of charactes. */
  273.  
  274. void put_string(int x, int y, char *string, byte color, byte option)
  275. {
  276.  word a=0;
  277.  
  278.  while (string[a]!='\0')
  279.  {
  280.   put_font(x,y,string[a],color,option);
  281.   x+=8;
  282.   a++;
  283.  }
  284. }
  285.  
  286. /****************************************************************************/
  287. /****************************************************************************/
  288. /****************************************************************************/
  289.  
  290. /* same here.  just display a string of numbers. */
  291.  
  292. void put_number_i(int x, int y, int number, byte color, byte option)
  293. {
  294.  word a=0;
  295.  byte buf[17];
  296.  
  297.  itoa(number,buf,10);
  298.  put_string(x,y,buf,color,option);
  299. }
  300.  
  301. /****************************************************************************/
  302. /****************************************************************************/
  303. /****************************************************************************/
  304.  
  305. void put_number_l(int x, int y, long number, byte color, byte option)
  306. {
  307.  word a=0;
  308.  byte buf[17];
  309.  
  310.  ltoa(number,buf,10);
  311.  put_string(x,y,buf,color,option);
  312. }
  313.  
  314. /****************************************************************************/
  315. /****************************************************************************/
  316. /****************************************************************************/
  317.  
  318. /* reads a 256 character 8x8 font stored as 8 bytes per character */
  319.  
  320. byte read_font(char *filename)
  321. {
  322.  char buf[80];
  323.  size_t itemsread;
  324.  FILE *file;
  325.  int a;
  326.  
  327.  sprintf(buf,"%s%s.fnt",path,filename);
  328.  
  329.  if ((file=fopen(buf,"rb"))==NULL)
  330.  {
  331.   printf("Unable to open %s for read.\n",buf);
  332.   return (FAILURE);
  333.  }
  334.  for (a=0;a<FONT_CHARACTERS;a++)
  335.  {
  336.   itemsread=fread(font[a],1,FONT_CHARACTER_SIZE,file);
  337.  }
  338.  fclose(file);
  339.  
  340.  return(SUCCESS);
  341. }
  342.  
  343. /****************************************************************************/
  344. /****************************************************************************/
  345. /****************************************************************************/
  346.  
  347. /* writes one. */
  348.  
  349. byte write_font(char *filename)
  350. {
  351.  char buf[80];
  352.  size_t items_written;
  353.  FILE *file;
  354.  int a;
  355.  
  356.  sprintf(buf,"%s%s.fnt",path,filename);
  357.  
  358.  if ((file=fopen(buf,"rb"))==NULL)
  359.  {
  360.   printf("Unable to open %s for write.\n",buf);
  361.   return (FAILURE);
  362.  }
  363.  
  364.  for (a=0;a<FONT_CHARACTERS;a++)
  365.  {
  366.   items_written=fread(font[a],1,FONT_CHARACTER_SIZE,file);
  367.  }
  368.  fclose(file);
  369.  
  370.  return(SUCCESS);
  371. }
  372.  
  373. /* that's it for this file. hope it helps! */
  374.  
  375. /****************************************************************************/
  376. /****************************************************************************/
  377. /****************************************************************************/
  378.  
  379. byte allocate_font(void)
  380. {
  381.  int a;
  382.  
  383.  font=(byte huge **)halloc((long)(FONT_CHARACTERS),4);
  384.  if (font==NULL)
  385.  {
  386.   printf("error allocating font pointers\n");
  387.   return(FAILURE);
  388.  }
  389.  
  390.  for (a=0;a<FONT_CHARACTERS;a++)
  391.  {
  392.   font[a]=(byte huge *)halloc((long)(FONT_CHARACTER_SIZE),1);
  393.   if (font[a]==NULL)
  394.   {
  395.    printf("error allocating font %d\n",a);
  396.    return(FAILURE);
  397.   }
  398.  }
  399.  
  400.  return(SUCCESS);
  401. }
  402.  
  403. /****************************************************************************/
  404. /****************************************************************************/
  405. /****************************************************************************/
  406.  
  407. void free_font(void)
  408. {
  409.  int a;
  410.  
  411.  for (a=0;a<FONT_CHARACTERS;a++)
  412.   if (font[a]!=NULL) hfree(font[a]);
  413.  
  414.  if (font!=NULL) hfree(font);
  415. }
  416.